package com.gzc.just.play.last.war.loginserver.handler;

import com.gzc.just.play.last.war.common.annotation.MessageHandler;
import com.gzc.just.play.last.war.common.handler.SimpleMessageHandler;
import com.gzc.just.play.last.war.common.net.NetUtils;
import com.gzc.just.play.last.war.loginserver.service.AuthService;
import com.gzc.just.play.last.war.protobuf.gc.gctols.GCToLS;
import com.gzc.just.play.last.war.protobuf.ls.lstogc.LSToGC;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;

/**
 * 登录消息处理器
 * 处理用户登录请求
 */
@Component
@MessageHandler(name = "LoginMessageHandler", serverTypes = MessageHandler.ServerType.LOGIN_SERVER)
public class LoginMessageHandler implements SimpleMessageHandler {
    private static final Logger logger = LoggerFactory.getLogger(LoginMessageHandler.class);

    @Autowired
    private AuthService authService;

    // 使用正确的登录消息ID，与C++服务器保持一致
    private static final int LOGIN = 40961; // eMsgToLSFromGC_AskLogin
    private static final int LOGINRESULT = 512; // eMsgToGCFromLS_NotifyLoginResult
    private static final int BSADDR = 513; // eMsgToGCFromLS_NotifyServerBSAddr

    @Override
    public void handle(Object message, ChannelHandlerContext ctx) throws Exception {
        GCToLS.AskLogin askLogin = null;

        // 解析登录请求消息
        if (message instanceof byte[]) {
            // 从字节数组解析AskLogin消息
            askLogin = GCToLS.AskLogin.parseFrom((byte[]) message);
        } else if (message instanceof GCToLS.AskLogin) {
            askLogin = (GCToLS.AskLogin) message;
        } else {
            logger.error("Unexpected message type: {}", message.getClass().getName());
            sendLoginResult(ctx, -2);
            return;
        }
        
        if (askLogin == null) {
            logger.error("Failed to parse login message");
            sendLoginResult(ctx, -1);
            return;
        }

        // 验证登录信息
        String username = askLogin.getUin();
        String token = askLogin.getSessionid();
        int platform = askLogin.getPlatform();
        
        if (username == null || username.trim().isEmpty()) {
            logger.warn("Login request with empty uin");
            sendLoginResult(ctx, -1);
            return;
        }

        // 记录登录请求
        logger.info("Login request from platform={}, uin={}", platform, username);

        // 进行登录验证
        Map<String, Object> loginResult = authService.authenticate(username, token);

        // 检查登录结果
        boolean success = (Boolean) loginResult.getOrDefault("success", false);
        
        if (success) {
            // 登录成功，保存用户ID到通道上下文
            Long userId = (Long) loginResult.get("userId");
            io.netty.util.AttributeKey<Long> userIdKey = io.netty.util.AttributeKey.valueOf("userId");
            ctx.channel().attr(userIdKey).set(userId);

            // 1. 发送登录结果
            sendLoginResult(ctx, userId.intValue());
            logger.info("User {} (ID: {}) logged in successfully", username, userId);
            
            // 2. 发送BS服务器列表
            sendServerBSAddr(ctx);
        } else {
            // 发送失败响应
            sendLoginResult(ctx, -1);
            logger.warn("Login failed for user: {}", username);
        }
    }

    private void sendLoginResult(ChannelHandlerContext ctx, int result) {
        try {
            LSToGC.LoginResult response = LSToGC.LoginResult.newBuilder()
                .setResult(result)
                .setMsgid(LSToGC.MsgID.eMsgToGCFromLS_NotifyLoginResult)
                .build();
            NetUtils.sendMsg(ctx.channel(), LOGINRESULT, response);
        } catch (Exception e) {
            logger.error("Failed to send login result", e);
        }
    }
    
    private void sendServerBSAddr(ChannelHandlerContext ctx) {
        try {
            // 这里硬编码一个BS地址，实际应该从配置或服务发现获取
            LSToGC.ServerBSAddr.Builder builder = LSToGC.ServerBSAddr.newBuilder();
            builder.setMsgid(LSToGC.MsgID.eMsgToGCFromLS_NotifyServerBSAddr);
            
            LSToGC.ServerInfo.Builder serverInfo = LSToGC.ServerInfo.newBuilder();
            // serverInfo.setServerId(1); // Proto definition does not have ServerId
            serverInfo.setServerName("TestServer");
            serverInfo.setServerState(1); // 正常状态
            serverInfo.setServerAddr("127.0.0.1");
            serverInfo.setServerPort(9002); 
            
            builder.addServerinfo(serverInfo);
            
            LSToGC.ServerBSAddr response = builder.build();
            NetUtils.sendMsg(ctx.channel(), BSADDR, response);
            logger.info("Sent BS address list to client");
        } catch (Exception e) {
            logger.error("Failed to send BS address", e);
        }
    }

    @Override
    public int getMessageId() {
        return LOGIN;
    }

    @Override
    public String getName() {
        return "LoginMessageHandler";
    }

    @Override
    public Logger getLogger() {
        return logger;
    }
}